/*
 * unpack_dat.c
 *
 * Author: TalkLittle
 *
 * Separate the various dat files used by True Love, which are all packed
 * using same format. You need to know the offset of the first char of the
 * last (all 0's) line in the dat file.
 */
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>

int main(int argc, char **argv) {
    char *outdir, *outfile;
    char curr_file[12];
    char cmd[1024];
    char buf[1024];
    FILE *fp, *outfp;
    long endline, i;
    uint32_t offset, next_offset;
    int bytes_read;

    if (argc != 4) {
        fprintf(stderr, "Usage:\n"
                "unpack_dat <file> <offset of ending line> <output dir>\n");
        exit(1);
    }
    fp = fopen(argv[1], "rb");
    endline = atoi(argv[2]);
    outdir = strdup(argv[3]);
    outfile = (char *)malloc(13 + strlen(outdir)); // "outdir/curr_file"

    for (i = 2; i < endline; i += 16) {
        /* Get the next filename */
        fseek(fp, i, SEEK_SET);
        fread(curr_file, 1, 12, fp);
        /* Get the offset */
        fread(&offset, 1, 4, fp);
        fseek(fp, i+28, SEEK_SET);
        fread(&next_offset, 1, 4, fp);

        fseek(fp, offset, SEEK_SET);
        snprintf(outfile, 13+strlen(outdir), "%s/%s", outdir, curr_file);
        printf("%s\n", outfile);

        outfp = fopen(outfile, "wb");
        while (offset < next_offset) {
            if (next_offset - offset < sizeof(buf))
                bytes_read = fread(buf, 1, next_offset - offset, fp);
            else
                bytes_read = fread(buf, 1, sizeof(buf), fp);
            fwrite(buf, 1, bytes_read, outfp);
            offset += sizeof(buf);
        }
        fclose(outfp);
    }

    free(outfile);
    free(outdir);

    return 0;
}
